/*
 * BONDI API example - File System
 * The UI is minimal so that it doesn't interfere with the examples 
 * of the bondi.filesystem functionality.
 * 
 * Widget shows a file listing of the "documents" directory in a table.
 * Click on a directory to show a file listing for that directory.
 * Click on a file to show a preview of the file contents.
 * Click on [..] to go to the parent directory.
 * All directories for emulation in the SDK are specified in
 * Preferences > Samsung > Directories.
 * 
 * Having files and directories in your "documents" directory makes
 * this much more interesting. 
 * 
 * @see http://bondi.omtp.org/1.01/apis/filesystem.html
 */

/**
 * History for showDirectory parent chain.  
 * We are using this rather than File.parent
 * because File.parent is not supported in WRT 1.0
 */
var gHistory = new Array();

/**
 * appInit is called from index.html when the html content has been loaded.
 * Example of bondi.filesystem.resolve
 * @see http://bondi.omtp.org/1.01/apis/filesystem.html#resolveN10211
 */
function appInit() {
    try {
    	var docLocation = bondi.filesystem.getDefaultLocation("documents");
    	
    	//var directory = bondi.filesystem.resolve(docLocation);
    	//showDirectory(directory);
    	//var directory2 = bondi.filesystem.resolve(docLocation + "TodayAppStorage");
    	//showDirectory(directory2);
    	
    	var mydoc = bondi.filesystem.resolve(docLocation + "TodayAppStorage/TodayAppConfig.txt");
    	
    	//alert(directory + "/TodayAppStorage/TodayAppConfig.txt");
    	
    	/*
        // list directory contents
        var files = dir.listFiles();
        for(var i = 0; i < files.length; i++) {
                // alerts each name of dir's contents
                alert(files[i].name);
        }
		*/ 
        // opens a file for writing
        //var file = dir.createFile("test.txt");
        //var out  = file.open("w", "UTF-8");
        // writes Hello World to test.txt
        //out.write("Hello World");
        //out.close();

    	/*
        alert(mydoc.created); // displays the creation timestamp
        alert(mydoc.path); // should be /baz/ if the file is /baz/foo.bar
        alert(mydoc.name); // should be foo.bar if the file path is /baz/foo.bar
        alert(mydoc.absolutePath); // should be /baz/foo.bar if the file is /baz/foo.bar
        alert(mydoc.fileSize); // displays the file size
        */
        
    	showFileContents(mydoc);
    }
    catch (err) {
        showError(err.code);
    }
}

/**
 * Display the first 512 characters of a file.
 * Example of File.open, FileStream.read, FileStream.close, File.parent
 * @see http://bondi.omtp.org/1.01/apis/filesystem.html#openN105E4
 * @see http://bondi.omtp.org/1.01/apis/filesystem.html#readN10B24
 * @see http://bondi.omtp.org/1.01/apis/filesystem.html#closeN10B06
 * @see http://bondi.omtp.org/1.01/apis/filesystem.html#File
 */
function showFileContents(file) {
	// File.open will throw an exception if attempted on a directory
	clearTable("table", [file.name]);
	var stream;
	try {
		stream = file.open("r", "UTF-8");
		var contents = stream.read(512);
	
		addTableRow("table", [contents], function() { }, null);

		addTableRow("table", ["[..]"], function(aFile) {
			var parent = gHistory.pop();
			showDirectory(parent);
		}, file);
	}
	finally {
		// Always close the stream when done with it
		if (stream) {
			stream.close();
		}
	}
	
	// make sure we can see all the preview contents
	widget.window.setScroll(true);
}

/**
 * Iterate through the specified directory and list each file.
 * Example of File.listFiles, File properties
 * @see http://bondi.omtp.org/1.01/apis/filesystem.html#listFilesN1058E
 */
function showDirectory(directory) {

		clearTable("table", [directory.name, ""]);
		try {
			var files = directory.listFiles();
			for (var i in files) {
				var file = files[i];
				var filename = file.name;
				var modified = file.modified;
				// notice that we can test a File for isFile or isDirectory
				// for a file, show the contents
				// for a directory, show the file listing
				if (files[i].isFile) {
					addTableRow("table", [filename, modified.toUTCString()], function(aFile) {
						gHistory.push(directory);
						showFileContents(aFile);
					}, file);
				}
				else {
					addTableRow("table", [filename, modified.toUTCString()], function(aFile) {
						gHistory.push(directory);
						showDirectory(aFile);
					}, file);
				}
			}
			
			// help for a new user when they don't see anything to begin
			if (files.length == 0) {
				addTableRow("table", ["[no files found]", "specify bondi directories in Preferences"], function(){ });
			}
		} 
		catch (err) {
			addTableRow("table", ["[exception]", getErrorMessage(err.code)], function(){ });
		}
	
		// If we have a parent, then allow navigation back to parent
		if (gHistory.length) {
			addTableRow("table", ["[..]",""], function(folder) {
				var parent = gHistory.pop();
				showDirectory(parent);
			}, null);
		}

		// make sure we can see all the listing
		widget.window.setScroll(true);
}

/**
 * Turn an error code into a message.
 * Example of using BONDI error codes.
 * @param code The {number} exception code
 * @return A readable message corresponding to code
 * @see http://bondi.omtp.org/1.01/apis/bondi.html#DeviceAPIError
 */
function getErrorMessage(code) {
	var message;
	switch(code) {
		case DeviceAPIError.INVALID_ARGUMENT_ERROR:
			message = "invalid argument error";
			break;
		case DeviceAPIError.IO_ERROR:
			message = "i/o error during operation";
			break;
		case SecurityError.PERMISSION_DENIED_ERROR:
			message = "permission denied error - enable feature in project.xml";
			break;
		case DeviceAPIError.NOT_FOUND_ERROR:
			message = "not found error";
			break;
		case DeviceAPIError.NOT_SUPPORTED_ERROR:
			message = "function not supported";
			break;
		case DeviceAPIError.PENDING_OPERATION_ERROR :
			message = "pending operation error";
			break;
		default:
			message = "unknown error : " + code;
			break;
	}
	
	return message;
}

/**
 * Utility function to show a gallery error in our table.
 * @param code
 */
function showError(code) {
    clearTable("table", ["Error"], [undefined]);
    
    var row = document.createElement("tr");
    row.appendChild(createTableCell("Exception: " + getErrorMessage(code)));
    document.getElementById("table").appendChild(row);
}

/**
 * Utility function to create a table cell, and set the contents.
 * @param content The {String} text contents for cell
 * @return The newly created cell element
 */
function createTableCell(content) {
	var cell = document.createElement("td");
	cell.appendChild(document.createTextNode(content));
	return cell;
}

/**
 * Utility function to add a row to a table.
 * @param id The {String} document id of table body 
 * @param cells The array of cell contents 
 * @param onclick The function to call when row is clicked
 * @param param The {File} parameter passed to the onclick handler
 */
function addTableRow(id, cells, onclick, param) {
	var row = document.createElement("tr");
	for (var i in cells) {
		row.appendChild(createTableCell(cells[i]));
	}
	
	row.addEventListener('click', function() {
		onclick(param);
	}, false);
	
	document.getElementById(id).appendChild(row);
}

/**
 * Utility function to clear the rows of a table.
 * @param id The {String} document id of table body 
 * @param headers The {array} contents of headers
 */
function clearTable(id, headers) {
	var table = document.getElementById(id);
	for (var i = table.rows.length-1; i >= 0; i--) {
		table.deleteRow(i);
	}
	
	var row = document.createElement("tr");
	for (var i in headers) {
		var header = document.createElement("th");
		header.appendChild(document.createTextNode(headers[i]));
		row.appendChild(header);
	}
	
	table.appendChild(row);
}
